<?php if(!defined('MS_XTIGER')) exit('Access Denied');
/**
 * Created by openXtiger.org.
 * User: xtiger
 * Date: 2009-6-10
 * Time: 21:21:51
 */
 

/*public */function xtb_database_route($op='',$db='') {
    if(empty($op)) $op = 'list';
    $setting = xt_load('model', 'settingmodel');
    $dbap = xt_load('cache', 'databases');
    if(empty($dbap[$db])) {
        $dbset = xt_load('dbset');
        global $_XC;
        $dbap = array($dbset['dbname'],$dbset['dbhost'],$_XC['tablepre'],
            $dbset['dbuser'],$dbset['dbpwd'],$dbset['dbport'],$_XC['pconnect'],$dbset['dbcharset']);
    }
    $backupdir = xt_hashmap(xt_load('cache', 'setting'),'backupdir');
    if(empty($backupdir)) {
	    $backupdir = xt_random(6);
	    $setting('replace','backupdir',$backupdir);
	    $setting('updatecache');
    }
    $backupdir = 'backup'.$db.'_'.$dbap[1].'_'.$dbap[2].$backupdir;
    $datadir = MS_APPPATH."./data/";
    if(!is_dir($datadir.$backupdir)) {
        @mkdir($datadir.$backupdir, 0777);
    }
    switch($op) {
        case 'export':
            database_action_export($dbap);
            return 'database_export';
        case 'backupstart':
            return database_action_backupstart($datadir,$backupdir);
        case 'import':
            return database_action_import($datadir,$backupdir);;
        case 'importstart':
            return database_action_importstart($datadir,$backupdir);;
        case 'importaction':
            return  database_action_importaction($datadir);;
    }
    return 'database_list';
}
/*private */function database_action_export($dbap) {
    $dbm = xt_load('model', 'databasemodel');
    xt_set('shelldisabled',function_exists('shell_exec') ? '' : 'disabled');
    $dbversion = $dbm('version');
    xt_set('dbversion',$dbversion);
    xt_set('dbcharset',strtoupper($dbap[7]));
    xt_set('zipdisplay',function_exists('gzcompress') ? '' : 'style="display:none"');
    xt_set('filename',date('ymd').'_'.xt_random(8));
    xt_set('xt_tablelist', $dbm('fetchtablelist',$dbap));
}

/*private */function database_action_backupstart($datadir,$backupdir) {
    //models
    $dbm = xt_load('model', 'databasemodel');
    $setting = xt_load('model', 'settingmodel');
    //gets or posts
    $filename = xt_get('filename');
	$type = xt_get('type');
	$sqlcharset = xt_get('sqlcharset');
	$sqlcompat = xt_get('sqlcompat');
	$sizelimit = xt_get('sizelimit');
	$usezip = xt_get('usezip');
	$method = xt_get('method');
	$extendins = xt_get('extendins');
	$usehex = xt_get('usehex');
	$volume = xt_get('volume',0) + 1;

	$filename = preg_replace("/[^a-z0-9_]/i", '',(str_replace('.', '_', $filename)));
	if(empty($filename) || strlen($filename) > 40) {
		return xtr_message('database_export_filename_error');
	}
	//idstring:e,version,type,method,volume
	$idstring = '# Identify: '.base64_encode("e,".XT_VERSION.",$type,$method,$volume")."\n";
	if($type == 'xbuilder') {
		$tables = system_arraykeys2($dbm('fetchtablelist',xt_config('tablepre')), 'Name');
	} elseif ($type == 'custom') {
		if(xt_get('setup')) {   // post
		    $tables = xt_get('customtables');
			if(empty($tables)){ $tables = array(); }
			$tablesnew = addslashes(serialize($tables));
			$setting('replace','custombackup',$tablesnew);
		} else {    // get
		    if($tables = $setting('replace','custombackup')){
	            $tables = unserialize($tables);
            }
        }
	}

	if(empty($tables) && is_array($tables)) {
		return xtr_message('database_export_tables_error');
	}
	
	$dbversion = $dbm('version');
	$dumpcharset = $sqlcharset;
	$setnames = ($sqlcharset && $dbversion > '4.1' && (!$sqlcompat || $sqlcompat == 'MYSQL41')) ? "SET NAMES '$dumpcharset';\n\n" : '';

    if($dbversion > '4.1') {
        if($sqlcharset) {
            $dbm('set','NAMES',$sqlcharset);
        }
        if($sqlcompat == 'MYSQL40') {
            $dbm('set','SQL_MODE','MYSQL40');
        } elseif ($sqlcompat == 'MYSQL41') {
            $dbm('set','SQL_MODE','');
        }
    }
	
	$backupfile = $datadir.$backupdir.'/'.$filename;
    if($method == 'multivol') {
        $tableidx = xt_get('tableidx',0);
        $startfrom = xt_get('startfrom',0);
        $sqldump = '';
		$tablenum = count($tables);
		$filesize = $sizelimit * 1000;
		$complate = true;
		for( ; $complate && $tableidx < $tablenum && strlen($sqldump) + 500 < $filesize; ++$tableidx) {
			$r = $dbm('sqldumptable',$tables[$tableidx], $startfrom, strlen($sqldump),
			    $sqlcompat,$sqlcharset,$dumpcharset,$extendins,$filesize,$usehex,$complate);
			if(is_array($r)) {
			    $sqldump .= $r[2];
			    $complate = $r[0];
			    $startrows = $r[1];     
           }
			if($complate) {
				$startfrom = 0;
			}
		}

		$dumpfile = sprintf($backupfile.'-%s'.'.sql', $volume);
		!$complate && $tableidx --;
		if(trim($sqldump)) {
			$sqldump = "$idstring".
			"# Made in xnetframwork!\n".
			"# ---------------------------------------------------------\n\n\n".
			"$setnames".$sqldump;
			$fp = fopen($dumpfile, 'wb');
			@flock($fp, 2);
			if(!fwrite($fp, $sqldump)) {
				fclose($fp);
				return xtr_message('database_export_write_error');
			} else {
				fclose($fp);
				if($usezip == 2) {
					$zipfile = sprintf($backupfile.'-%s'.'.zip', $volume);
					$czip = xt_load('library', 'zip');
					if(empty($czip))  return xtr_message('database_export_zip_error');
					$zipfile = new $czip($zipfile);
					if(!$zipfile->create($dumpfile, PCLZIP_OPT_REMOVE_PATH, $datadir.'/'.$backupdir)) {
						return xtr_message('database_export_write_error');
					} else {
						@unlink($dumpfile);
					}
					//fclose($fp);
				}
				xt_set('volume',$volume) ;
				return xtr_message('database_export_multivol_redirect', '/database/route/backupstart?type='.rawurldecode($type).'&filename='.rawurlencode($filename).'&method=multivol&sizelimit='.intval($sizelimit).'&tableidx='.intval($tableidx).'&startfrom='.intval($startrows).'&extendins='.intval($extendins).'&sqlcharset='.rawurlencode($sqlcharset).'&sqlcompat='.rawurlencode($sqlcompat).'&usehex='.intval($usehex).'&usezip='.intval($usezip).'&volume='.intval($volume));
			}
		} else {

			if($usezip == 1) {
				$zipfile = $backupfile.'.zip';
				$czip = xt_load('library', 'zip');
			    if(empty($czip))  return xtr_message('database_export_zip_error');
				$unlinks = '';
				$arrayzipfile = array();
				for($i = 1; $i < $volume; ++$i){
					$dumpfile = sprintf($backupfile.'-%s'.'.sql', $i);
					$arrayzipfile[] = $dumpfile;
					$unlinks .= "@unlink('$dumpfile');";
				}
				if($zipfile->create($arrayzipfile, PCLZIP_OPT_REMOVE_PATH, $datadir.'/'.$backupdir)) {
					@eval($unlinks);
				} else {
				    xt_set('volume',($volume-1)) ;
					return xtr_message('database_export_multivol_succeed','/database/route/import');
				}
				fclose(fopen($datadir.'/'.$backupdir.'/index.htm', 'a'));
				return xtr_message('database_export_zip_succeed');
			} else {
				fclose(fopen($datadir.'/'.$backupdir.'/index.htm', 'a'));
				xt_set('volume',($volume-1)) ;
				return xtr_message('database_export_multivol_succeed','/database/route/import');
			}
		}
    } else {

        $tablesstr = '';
        foreach($tables as $value) {
            $tablesstr .= $value.' ';
        }

        $mysql_base =  $dbm('variable','basedir');

        $dumpfile = $backupfile.'.sql';
        if(file_exists($dumpfile))
            @unlink($dumpfile);
        $mysqlbin = $mysql_base == '/' ? '' : addslashes($mysql_base).'bin/';
        extract(xt_load('dbset'));
        @shell_exec('"'.$mysqlbin.'mysqldump" --force --quick --default-character-set='.$dbcharset.' '.($dbversion > 4.1 ? '--skip-opt --create-options' : '-all').' --add-drop-table'.($extendins == 1 ? '--extended-insert' : '').''.($dbversion > '4.1' && $sqlcompat == 'MYSQL40' ? '--compatible=mysql40' : '').' --host='.$dbhost.($dbport ? (is_numeric($dbport) ? ' --port='.$dbport : ' --sock='.$dbport) : '').' --user='.$dbuser.' --password='.$dbpwd.' '.$dbname.' '.$tablesstr.' > '.$dumpfile);

        if(file_exists($dumpfile)) {
            if(is_writable($dumpfile)) {
                $fp = fopen($dumpfile, 'rb+');
                fwrite($fp,  $idstring."# Made in xnetframwork!\n ".$setnames."\n #");
                fclose($fp);
            }

            if($usezip) {
                $zipfilename = $backupfile.'.zip';
                $czip = xt_load('library', 'zip');
                if(empty($czip))  return xtr_message('database_export_zip_error');
                $zipfile = new $czip($zipfilename);
                if($zipfile->create($dumpfile, PCLZIP_OPT_REMOVE_PATH, $datadir.'/'.$backupdir)) {
                    @unlink($dumpfile);
                    fclose(fopen($datadir.'/'.$backupdir.'/index.htm', 'a'));
                    return xtr_message('database_export_zip_succeed','/database/route/import');
                } else {
                    return xtr_message('database_export_zip_error');
                }
            } else {
                fclose(fopen($datadir.'/'.$backupdir.'/index.htm', 'a'));
                return xtr_message('database_export_succeed','/database/route/import');
            }
        } else {
            return xtr_message('database_shell_faile');
        }
    }
	return NONE;//xtr_redirect('system/database/export');
}
/*private */function database_action_import($datadir,$backupdir) {
    $exportlog = array();
	if(is_dir($datadir.$backupdir)) {
		$dir = dir($datadir.$backupdir);
		while(FALSE !== ($entry = $dir->read())) {
			$filename = $datadir.'/'.$backupdir.'/'.$entry;
			$basefile = $backupdir.'/'.$entry;
			if(is_file($filename)) {
				$filesize = filesize($filename);
				if(preg_match('/\.sql$/i', $filename)) {
					$fp = fopen($filename, 'rb');
					$identify = explode(',', base64_decode(preg_replace('/^# Identify:\s*(\w+).*/s', '\\1', fgets($fp, 256))));
					if(count($identify) < 5){ $identify=array('','','','','',''); }
					fclose($fp);
					$exportlog[] = array(
						'version' => $identify[1],
						'type' => $identify[2],
						'method' => $identify[3],
						'volume' => $identify[4],
						'filename' => $basefile,
						'dateline' => filemtime($filename),
						'size' => $filesize
						);
				} elseif(preg_match('/\.zip$/i', $filename)) {
					$exportlog[] = array(
						'version' => '',
						'volume' => '',
						'type' => 'zip',
						'filename' => $basefile,
						'size' => $filesize,
						'dateline' => filemtime($filename),
						'method' => '',
					);
				}
			}
		}
		$dir->close();
	} else {
		return xtr_message('database_export_dest_invalid');
	}
	xt_set('backupdir',$backupdir);
	xt_set('exportlog',$exportlog);
	return 'database_import';
}
/*private */function database_action_importstart($datadir,$backupdir) {
    $do = xt_get('do') ;
	$delunzip = xt_get('delunzip');
	$datafile = xt_get('datafile');
	$confirm = xt_get('confirm');
	$multivol = xt_get('multivol',0);
	$datafile_vol1 = xt_get('datafile_vol1');
	$autoimport = xt_get('autoimport');
	if($do == 'zip') {
        $cunzip = xt_load('library', 'unzip');
        if(empty($cunzip))  return xtr_message('database_import_zip_error');
        $unzip = new $cunzip();
		$unzip->ReadFile($datadir.'/'.$datafile);

		if($unzip->Count() == 0 || $unzip->GetError(0) != 0 || !preg_match('/\.sql$/i', $importfile = $unzip->GetName(0))) {
			return xtr_message('database_import_file_illegal');
		}

		$identify = explode(',', base64_decode(preg_replace('/^# identify:\s*(\w+).*/s', '\\1', substr($unzip->GetData(0), 0, 256))));
		if(count($identify) < 5)
		    return xtr_message('database_import_file_illegal'); 
		$confirm = isset($confirm) ? 1 : 0;
		if(!$confirm && $identify[1] != XT_VERSION) {
		    return  database_message('database_import_confirm','do=zip&datafile='.$datafile.'&confirm=yes');     
		}
		$sqlfilecount = 0;
		foreach($unzip->Entries as $entry) {
			if(preg_match('/\.sql$/i', $entry->Name)) {
				$fp = fopen($datadir.'/'.$backupdir.'/'.$entry->Name, 'w');
				fwrite($fp, $entry->Data);
				fclose($fp);
				$sqlfilecount++;
			}
		}

		if(!$sqlfilecount) {
			return xtr_message('database_import_file_illegal');
		}
		$datafile_vol1 = isset($datafile_vol1) ? $datafile_vol1 : '';
		if(!empty($multivol)) {
			$multivol++;
			$datafile = preg_replace('/-(\d+)(\..+)$/', "-$multivol\\2", $datafile);
			if(file_exists($datadir.'/'.$datafile)) {
                xt_set('multivol',$multivol);
                return xtr_message('database_import_multivol_unzip_redirect', '/database/route/importstart?do=zip&multivol='.$multivol.'&datafile_vol1='.$datafile_vol1.'&datafile='.$datafile.'&confirm=yes');
            } else{
                return database_message('database_import_multivol_confirm','do=import&datafile='.$datafile_vol1.'&delunzip=yes');       
            }
	    }
	    //
	    if($identify[3] == 'multivol' && $identify[4] == 1 && preg_match("/-1(\..+)$/", $datafile)) {
	        $datafile_vol1 = $datafile;
			$datafile = preg_replace('/-1(\..+)$/', '-2\\1', $datafile);
			if(file_exists($datadir.'/'.$datafile)) {
			    return database_message('database_import_multivol_unzip',"do=zip&multivol=1&datafile_vol1=$backupdir/$importfile&datafile=$datafile&confirm=yes"); 
			}
	    }
	    return database_message('database_import_unzip_success',"do=import&datafile=$backupdir/$importfile&delunzip=yes");
	} elseif($do == 'import') {
	    $sqldump = '';
		$datafile_root = $datadir.'/'.$datafile;

		if(file_exists($datafile_root) && $fp = @fopen($datafile_root, 'rb')) {
			$sqldump = fgets($fp, 256);
			$identify = explode(',', base64_decode(preg_replace('/^# Identify:\s*(\w+).*/s', '\\1', $sqldump)));
			if(count($identify)<5)
		        return xtr_message('database_import_file_illegal'); 
			if($identify[3] == 'multivol') {
				$sqldump .= fread($fp,filesize($datafile_root));
			}
			fclose($fp);
		} else {
			if(isset($autoimport)) {
				return xtr_message('database_import_multivol_succeed', '/database/route/import');
			} else {
				return xtr_message('database_import_file_illegal');
			}
		}

		if($identify[3] == 'multivol') {
		    $dbm = xt_load('model','databasemodel');
		    $dbset = xt_load('dbset');
		    if(!$dbm('sqlimport',$sqldump,$dbset['dbcharset'])){
                return xtr_message('database_import_format_illegal'); 
            }
			if($delunzip == 'yes') {
				@unlink($datadir.'/'.$datafile);
			}

			$identify[4] = intval($identify[4]);
			$datafile_next = preg_replace("/-($identify[4])(\..+)$/", '-'.($identify[4] + 1).'\\2', $datafile);

			if($identify[4] == 1) {
			    return database_message('database_import_multivol_prompt',"do=import&datafile=$datafile_next&autoimport=yes".(isset($unzip) ? '&delunzip=yes' : ''));
			} elseif (isset($autoimport)) {
			     xt_set('multivol',$identify[4]);
				return xtr_message('database_import_multivol_redirect', "/database/route/importstart?do=import&datafile=$datafile_next&autoimport=yes".(isset($unzip) ? '&delunzip=yes' : ''));
			} else {
				return xtr_message('database_import_success','/database/route/import');
			}
		} elseif($identify[3] == 'shell') {
            $dbm = xt_load('model', 'databasemodel');
			$mysql_base =  $dbm('variable','basedir');
            $mysqlbin = $mysql_base == '/' ? '' : addslashes($mysql_base).'bin/';
			$datafile_root = addslashes($datafile_root);
			extract(xt_load('dbset'));
			@shell_exec('"'.$mysqlbin.'mysql" --default-character-set='.$dbcharset.' -h '.$dbhost.($dbport ? (is_numeric($dbport) ? ' -P'.$dbport : ' -S'.$dbport.'') : '').' -u'.$dbuser.' -p'.$dbpwd.' '.$dbname.' < '.$datafile_root);
			return xtr_message('database_import_successd');
		} else {
			return xtr_message('database_import_format_illegal');
		}       
	}
}
/*private */function database_action_importaction($datadir) {
    if(xt_get('listsubmit')){
        $delexport = xt_get('delexport');
        if(!empty($delexport) && is_array($delexport)) {
            foreach($delexport as $value) {
                $fileext = xt_fileext($value);
                if($fileext != 'sql' && $fileext != 'zip') {
                    continue;
                }
                $value = str_replace('..', '', $value);
                if (file_exists($datadir.'/'.$value)){
                    @unlink($datadir.'/'.$value);
                }
            }
        }
	    return xtr_message('database_export_del', '/database/route/import');
    }else if(xt_get('importsubmit')) {
        $datafile = str_replace('..', '', xt_get('datafile'));
        if(!file_exists($datadir.'/'.$datafile)) {
            return xtr_message('database_import_file_illegal');
        } else {
            $fileext = xt_fileext($datafile);
            if($fileext == 'sql') {
                return xtr_message('database_import_start', '/database/route/importstart?do=import&datafile='.$datafile);
            } elseif($fileext == 'zip') {
                return xtr_message('database_import_start', '/database/route/importstart?do=zip&datafile='.$datafile);
            } else {
                return xtr_message('database_import_file_illegal');
            }
        }
    }
}
/*private */function database_message($msg, $actionuri) {
    xt_set('message',$msg);
    xt_set('importurl',xt_uri('/database/route/import'));
    xt_set('actionuri',xt_uri('/database/route/importstart?'.$actionuri));
    return 'database_message';
}
/*private */function system_arraykeys2($array, $key2) {
	$return = array();
	foreach($array as $value) {
		$return[] = $value[$key2];
	}
	return $return;
}

?>